查看原文
其他

反射型DLL技术介绍

SpearMint 看雪学院 2019-05-26

大家好,这篇文章将介绍反射型动态链接库(DLL),并将简单介绍如何编写。这是由Stephen Fewer开发的一种技术,我们将使用他的代码来见证奇迹。我知道这个话题已经被讨论过多次了,所以我会简明扼要地写这篇文章。



参考


  • http://blog.opensecurityresearch.com/2013/01/windows-dll-injection-basics.html


  • https://github.com/stephenfewer/ReflectiveDLLInjection


什么是DLL?


DLL是可移植代码,通常被应用程序所共享。但是,就这篇文章而言,DLL可以让我们有机会执行代码。为什么要这么做呢?如果我们的目标是执行代码,为什么不在磁盘上写一个exe?暂且考虑下其占用的空间:写入磁盘,创建进程,然后运行;占用的空间会快速增加。进入DLL,加载DLL到内存的过程是如何呢?

 

通常,在进程启动时,DLL被加载到内存中;但是,DLL也可以注入到正在运行的进程中。通过DLL注入,我们不再需要创建进程来执行代码(各种DLL注入技术);但是,我们仍然需要将文件写入磁盘才能完成注入。反射型DLL注入解决了这个问题。该技术由Stephen Fewer开发,允许我们将代码注入现有进程而无需写入磁盘。因此,利用型反射DLL注入,我们可以跳过写入磁盘以及创建进程,直接将代码完整注入内存...谢谢Stephen。



如何防御或检测


终端防护平台(EPP)逐渐开始标记这些技术。就我个人而言,我会在运行EPP软件的终端上研究反射型DLL注入,看有没有可以突破的地方。此外,反射型DLL通常会调用Windows API来执行恶意代码,这是一个潜在的检测点。例如,createremotethread是一种流行的在远程进程中执行shellcode的技术。

 

在看了Raphael最新的关于in-memory evasion的文章后,下面还列出了其他一些工具:


  • GET-InjectedThread

  • Reflective-injection-detection(未验证)

  • LOKI(未验证)



步骤


以下演示步骤是使用Visual Studio 2017完成的。


  • 下载Stephen Fewer的Reflective DLL库;

  • 创建一个新的project:C++ -> Windows Desktop -> Dynamic-Link Library;

  • 删除stdafx.h,stdafx.cpp,targetver.h和*project name*.cpp;

  • 从Reflective DLL库中,复制并添加ReflectiveDLLInjection.h,ReflectiveLoader.c和ReflectiveLoader.h到project中。


  • Project -> Properties


  • C/C++ -> Precompiled Headers -> 将Precompiled Headers设置为“Not Using Precompiled Headers”(因为我们删除了stdafx.h);


  • C/C++ -> Preprocessor -> Preprocessor Defintions -> 将Processor Defintions设置为以下(对于x64 DLL,用WIN64和WIN_X64替换WIN32和WIN_X86...我意识到有更好的方法):


WIN32; WIN_X86; NDEBUG; _WINDOWS; _USRDLL; RDLL_EXPORTS; REFLECTIVE_DLL_EXPORTS; REFLECTIVEDLLINJECTION_VIA_LOADREMOTELIBRARYR; REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN;



  • dllmain.cpp应如下所示:


注意,lpReserved保留用于在运行期间可以传递给我们的代码的参数(或shellcode)。我确信Metasploit可以传递参数,但我不太清楚怎么做。Cobalt Strike绝对是可以的,相关信息参见:


https://www.cobaltstrike.com/aggressor-script/functions.html

    // dllmain.cpp : Defines the entry point for the DLL application.
    #include "ReflectiveLoader.h"
    #include <stdio.h>
    void PartyTime()
    {
      MessageBox(0, "PartyTime", "PartyTime", MB_OK);
      return;
    }

    extern "C" HINSTANCE hAppInstance;
    BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
    {  
      switch (ul_reason_for_call)  
      {
         case DLL_QUERY_HMODULE:
            if (lpReserved != NULL)
               {
                  *(HMODULE *)lpReserved = hAppInstance;
               }
            break;
         case DLL_PROCESS_ATTACH:
            hAppInstance = hModule;
            if (!lpReserved != NULL)
            {
               printf("Parameter passed to Reflective DLL: %s", (char *)lpReserved);
            }
            else
            {
               printf("No parameter passed to Reflective DLL");
            }
            PartyTime();
            fflush(stdout);
            ExitProcess(0);
            break;  
         case DLL_THREAD_ATTACH:  
         case DLL_THREAD_DETACH:  
         case DLL_PROCESS_DETACH:      
         break;  
      }  
      return TRUE;
    }



    • 编译


    编译好我们的反射型DLL(希望如此),我们应该就能在无需写入磁盘的情况下实现注入。 Metasploit,Cobalt Strike和Empire(不确定)都有用于自定义反射型DLL注入的post exploitation模块。

     

    Metasploit:

     

    在WIN10-DM桌面上:

     

    这种技术虽然有点过时但是还算好用。如果你使过任何流行的C2平台,那么你可能已经用过了反射型DLL注入。安全解决方案在捕获类似的内存攻击技术的方面做得越来越好,但是高级威胁攻击者针对对抗技术的适应能力也变得越来越强。


    在我看来,测试你的安全解决方案,看它是如何处理基本的反射型DLL注入,并不是一个坏主意。 像Meterpreter,Empire(不确定)和Cobalt Strike这样的post exploitation工具也使用反射型DLL,研究下究竟是什么会被标记以及原因,有益无害。

     

    祝好。



    - End -



    看雪ID:SpearMint                                      

    https://bbs.pediy.com/user-747358.htm




    本文由看雪翻译小组 SpearMint 编译,sudozhange校对

    来源cplsec@Ijustwannaredteam

    转载请注明来自看雪社区



    好书推荐:

    立即购买!



    热门技术文章推荐:




    公众号ID:ikanxue
    官方微博:看雪安全

    商务合作:wsc@kanxue.com

      您可能也对以下帖子感兴趣

      文章有问题?点此查看未经处理的缓存